package com.sccdlg.es;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Before;
import org.junit.Test;

import java.net.InetAddress;
import java.util.Iterator;
import java.util.Map;

/**
 * @author RaoShuang
 * @emil 991207823@qq.com
 * @date 2020/9/23 23:34
 * 测试ES-Java客户端查询文档
 * es版本：7.4.2
 */
public class SearchIndexTest {
    /** 客户端Client对象 */
    private TransportClient client;

    @Before
    public void init() throws Exception {
        //1、创建一个Settings对象，相当于是一个配置信息。主要配置集群的名称。
        Settings settings = Settings.builder()
                .put("cluster.name", "my-elasticsearch")
                .build();
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.235.129"),9300));
    }

    /**
     * 根据id查询es中存储的文档
     */
    @Test
    public void testSearchById() throws Exception {
        //1、创建一个Client对象
        //2、创建一个查询对象。
        QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("1","3");
        search(queryBuilder);
    }

    /**
     * 根据关键字查询
     */
    @Test
    public void testSearchByTerm() throws Exception {
        //1、创建一个查询对象（queryBuilder对象）。
        //参数1：要搜索的字段，参数2：要查询的关键字
        QueryBuilder queryBuilder = QueryBuilders.termQuery("title","北方");
        search(queryBuilder);
    }

    /**
     * 带分析的查询，会根据传递内容进行检索查询数据
     */
    @Test
    public void testQueryStringQuery() throws Exception {
        //1、创建一个查询对象（queryBuilder对象）
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("我爱你，中国")
                .defaultField("content");
        search(queryBuilder);
    }

    /**
     * 根据传递的查询对象查询数据
     * @param queryBuilder
     */
    private void search(QueryBuilder queryBuilder) {
        //3、使用client执行查询
        SearchResponse searchResponse = client.prepareSearch("index_hello")
                .setTypes("article")
                .setQuery(queryBuilder)
                //设置分页参数（默认10条）
                .setFrom(10).setSize(20)
                .get();
        //4、得到查询的结果。
        SearchHits hits = searchResponse.getHits();
        //5、取查询结鬼的总记录数
        System.out.println("查询结果总记录数：" + hits.getTotalHits());
        //6、取查询结果列表
        Iterator<SearchHit> iterator = hits.iterator();
        while (iterator.hasNext()) {
            SearchHit searchHit = iterator.next();
            //打印文档对象，以json格式输出
            System.out.println(searchHit.getSourceAsString());
            //取文档的属性
            System.out.println("-----------文档的属性");
            Map<String, Object> document = searchHit.getSourceAsMap();
            System.out.println("id=" + document.get("id"));
            System.out.println("title=" + document.get("title"));
            System.out.println("content=" + document.get("content"));
        }
        //7、关闭client
        client.close();
    }

    /**
     * 带分析的查询，会根据传递内容进行检索查询数据
     */
    @Test
    public void testQueryStringQuery2() throws Exception {
        //1、创建一个查询对象（queryBuilder对象）
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("北京")
                .defaultField("content");
        search(queryBuilder,"content");
    }

    /**
     * 根据传递的查询对象查询数据,显示高亮信息
     * @param queryBuilder
     */
    private void search(QueryBuilder queryBuilder, String highlightFiled) throws Exception{
        //设置高亮显示的字段
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field(highlightFiled);
        highlightBuilder.preTags("<em>");
        highlightBuilder.postTags("</em>");
        //3、使用client执行查询
        SearchResponse searchResponse = client.prepareSearch("index_hello")
                .setTypes("article").setQuery(queryBuilder)
                //设置分页参数（默认10条）
                .setFrom(0).setSize(10)
                //设置高亮信息
                .highlighter(highlightBuilder)
                .get();
        //4、得到查询的结果。
        SearchHits hits = searchResponse.getHits();
        //5、取查询结鬼的总记录数
        System.out.println("查询结果总记录数：" + hits.getTotalHits());
        //6、取查询结果列表
        Iterator<SearchHit> iterator = hits.iterator();
        while (iterator.hasNext()) {
            SearchHit searchHit = iterator.next();
            //打印文档对象，以json格式输出
            System.out.println(searchHit.getSourceAsString());
            //取文档的属性
            System.out.println("***********高亮结果");
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            System.out.println(highlightFields);
            //取Field域高亮显示的结果
            HighlightField highlightField = highlightFields.get(highlightFiled);
            Text[] fragments = highlightField.getFragments();
            if (fragments != null) {
                String title = fragments[0].toString();
                System.out.println(title);
            }
        }
        //7、关闭client
        client.close();
    }
}
